package com.songtech.uitest.aspects;

import com.songtech.uitest.components.ScreenShoter;
import com.songtech.uitest.entities.Indent;
import com.songtech.uitest.util.Assertion;
import com.songtech.uitest.util.Space;
import com.songtech.uitest.util.SpringUtil;
import com.songtech.uitest.util.SumUpHelper;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Aspect
@Component
public class LogAspect {

    //打印日志前的缩进空格
    @Autowired
    private Space space;

    @Autowired
    private ScreenShoter screenShoter;

    @Autowired
    private SumUpHelper sumUpHelper;

    @Autowired
    private Indent indent;

    private Logger logger = LoggerFactory.getLogger(LogAspect.class);


//    @Pointcut("within(com.songtech.uitest.modules..*) ! execution(com.songtech.uitest.modules..*.set*(..))")
//    @Pointcut("within(com.songtech.uitest.modules..*)")
    @Pointcut("execution(public * com.songtech.uitest.module..*(..))")
    public void logPointCut(){ }



    @Before("logPointCut()")
    public void before(JoinPoint joinPoint){
        space.addSpace();
        logger.info(space.getSpace() + "进入{}类的{}方法",
                new Object[]{joinPoint.getTarget().getClass().getSimpleName(),
                                joinPoint.getSignature().getName()});

    }

    @AfterReturning(pointcut="logPointCut()", returning = "returnVal")
    public void AfterReturning(JoinPoint joinPoint, Object returnVal){
        if(returnVal != null) {
//            logger.info("退出{}类的{}方法,返回结果为：{}",
//                    new Object[]{joinPoint.getTarget().getClass().getName(),
//                            joinPoint.getSignature().getName(),
//                            returnVal});
            logger.info(space.getSpace() + "退出{}类的{}方法,返回结果为：{}",
                    joinPoint.getTarget().getClass().getSimpleName(),
                            joinPoint.getSignature().getName(),
                            returnVal);
        }
        else{
            logger.info(space.getSpace() + "退出{}类的{}方法",
                    new Object[]{joinPoint.getTarget().getClass().getSimpleName(),
                            joinPoint.getSignature().getName()});
        }
        space.delSpace();

    }

    @AfterThrowing(pointcut="logPointCut()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Throwable e) throws Exception{

        //如果是断言抛出的异常(那一定是致命异常)，则不要截图和汇总了，交由Assertion.java去处理
        if(Assertion.fatal){return;}

        Object[] params = joinPoint.getArgs();

        String clsName = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();


        int pos = indent.getStepPosition();
        String stepNum = indent.getFlow().split(",")[pos];
        String msg = "执行" + clsName + "类" + methodName + "方法的流程失败。流程编码：" + stepNum + "，流程下标：" + pos;
        logger.error(space.getSpace() + msg);
        logger.error(space.getSpace() + "异常信息如下：", e);

        //记录到汇总类
        sumUpHelper.getFlowErrorList().add(msg + "异常信息为：" + StringUtils.substringBefore(e.getMessage(), "\n"));


        screenShoter.screenShot(new Object[]{clsName, methodName, "流程抛出异常"});

        space.delAllSpace();


    }



}
